package Thread;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;

public class Example_11_5 extends JFrame implements Runnable, ActionListener{
	
	private JLabel lblSendPort, lblReceivePort;   
	private JTextField textSendPort, textReceivePort; //发送、接收端口文本行
	private JTextArea textSendMessage, textShowMessage; //发送、接收消息文本域
	private JButton btnListen, btnSend;   //监听和发送按钮
	private Thread myThread = null;
	private DatagramPacket sendPacket, receivePacket;  //数据报对象
	private DatagramSocket sendSocket, receiveSocket;  //发送和接收数据报的套接字对象
	private InetAddress sendIP;   //目的地址
	private int sendPort, receivePort;  //存储发送端口和接收端口
	private byte[] inBuf, outBuf;    //接收和发送数据使用的缓冲区
	public static final int BUFSIZE = 1024;
	
	public Example_11_5(){
		super();
		getContentPane().setLayout(null);
		setTitle("基于UDP的聊天程序");
		setBounds(100, 100, 500, 375);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		lblSendPort = new JLabel();
		lblSendPort.setName("lblSendPort");
		lblSendPort.setText("发送端口：");
		lblSendPort.setBounds(24, 29, 60, 15);
		getContentPane().add(lblSendPort);
		
		lblReceivePort = new JLabel();
		lblReceivePort.setName("lblReceivePort");
		lblReceivePort.setText("接收端口：");
		lblReceivePort.setBounds(24, 62, 60, 15);
		getContentPane().add(lblReceivePort);
		
		textSendPort = new JTextField();
		textSendPort.setName("textSendPort");
		textSendPort.setBounds(90, 26, 90, 21);
		getContentPane().add(textSendPort);
		
		textReceivePort = new JTextField();
		textReceivePort.setName("textReceivePort");
		textReceivePort.setBounds(90, 59, 90, 21);
		getContentPane().add(textReceivePort);
		
		btnListen = new JButton();
		btnListen.addActionListener(this);
		btnListen.setName("btnListen");
		btnListen.setText("开始监听");
		btnListen.setBounds(24, 95, 156, 46);
		getContentPane().add(btnListen);
		
		textShowMessage = new JTextArea();
		textShowMessage.setRows(80);
		textShowMessage.setColumns(40);
		textShowMessage.setName("textShowMessage");
		textShowMessage.setBorder(new LineBorder(Color.BLACK, 1, false));
		textShowMessage.setBounds(206, 10, 276, 321);
		getContentPane().add(textShowMessage);
		
		btnSend = new JButton();
		btnSend.addActionListener(this);
		btnSend.setName("btnSend");
		btnSend.setText("发送");
		btnSend.setBounds(24, 296, 156, 35);
		getContentPane().add(btnSend);
		
		textSendMessage = new JTextArea();
		textSendMessage.setRows(40);
		textSendMessage.setColumns(20);
		textSendMessage.setName("textSendMessage");
		textSendMessage.setBorder(new LineBorder(Color.BLACK, 1, false));
		textSendMessage.setBounds(24, 147, 156, 143);
		getContentPane().add(textSendMessage);
		
		btnSend.setEnabled(false);
		textShowMessage.setEditable(false);
		textSendMessage.setEditable(false);
		
	}
	
	
	@Override
	public void actionPerformed(ActionEvent e) {
		try{
			if(e.getSource() == btnListen){
				if(textSendPort.getText().trim()==null || textReceivePort.getText().trim()==null){
					return;
				}
			
				inBuf = new byte[BUFSIZE];
				
				sendPort = Integer.parseInt(textSendPort.getText().trim());
				sendIP = InetAddress.getByName("localhost");
				sendSocket = new DatagramSocket();
				
				receivePort = Integer.parseInt(textReceivePort.getText());
				receivePacket = new DatagramPacket(inBuf, BUFSIZE);   //创建接收数据报
				receiveSocket = new DatagramSocket(receivePort);  //指定接收数据的端口
				
				myThread = new Thread(this);  //创建线程准备接收对方的消息
				myThread.setPriority(myThread.MIN_PRIORITY);
				myThread.start();
				
				btnListen.setEnabled(false);
				btnSend.setEnabled(true);
				textSendMessage.setEditable(true);
			}else{  // 按下发送按钮
				outBuf = textSendMessage.getText().getBytes();
				//打包要发送的数据
				sendPacket = new DatagramPacket(outBuf, outBuf.length, sendIP, sendPort);
				sendSocket.send(sendPacket); //发送数据
				textShowMessage.append("我说：" + textSendMessage.getText() + "\n");
				textSendMessage.setText(null);
			}
		}catch(UnknownHostException ee){
			textSendMessage.append("无法连接到指定地址\n");
		}catch(SocketException ee){
			textSendMessage.append("无法打开指定端口\n");
		}catch(IOException ee){
			textSendMessage.append("发送数据失败\n");
		}
	}

	@Override
	public void run() {  //在线程中接收数据
		String message = null;
		while(true){
			try{
				receiveSocket.receive(receivePacket);
				message = new String(receivePacket.getData(), 0, receivePacket.getLength());
				textShowMessage.append(sendIP.getHostAddress() + "说：" + message + "\n");
			}catch(IOException el){
				textShowMessage.append("接收数据出错\n");
			}
		}
	}
	
	public static void main(String[] agrs){
		try{
			Example_11_5 frame = new Example_11_5();
			frame.setVisible(true);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}
